///<reference path='../../../../../../../../test/lib/YUITest.d.ts'/>
///<reference path='../../../../../../../../bin/puremvc-typescript-multicore-1.1.d.ts'/>

module test
{
	"use strict";

	/**
	 * Tests PureMVC Observer class.
	 *
	 * Since the Observer encapsulates the interested object's callback information, there are no
	 * getters, only setters. It is, in effect write-only memory.
	 *
	 * Therefore, the only way to test it is to set the notification method and context and call the
	 * notifyObserver method.
	 */
	export class ObserverTest
	{
		/**
		 * The name of the test case - if not provided, one is automatically generated by the
		 * YUITest framework.
		 */
		name:string = "PureMVC Observer class tests";

		/**
		 * A test variable that proves the notify method was executed with 'this' as its execution
		 * context.
		 */
		observerTestVar:number = -1;

		/**
		 * Tests observer class when initialized by accessor methods.
		 */
		testObserverAccessors():void
		{
			/*
			 * Create observer with null args, then use accessors to set notification method and
			 * context.
			 */
			var observer:puremvc.IObserver = new puremvc.Observer( null, null );
			observer.setNotifyContext(this);
			observer.setNotifyMethod( this.observerTestMethod );

			/*
			 * Create a test event, setting a payload value and notify the observer with it. since
			 * the observer is this class and the notification method is observerTestMethod,
			 * successful notification will result in our local observerTestVar being set to the
			 * value we pass in on the notification body.
			 */
			var notification:puremvc.INotification = new puremvc.Notification( 'ObserverTestNote', 10 );
			observer.notifyObserver(notification);

			// test assertions
			YUITest.Assert.areSame
			(
				10,
				this.observerTestVar,
				"Expecting observerTestVar === 10"
			);
		}

		/**
		 * Tests observer class when initd by constructor.
		 */
		testObserverConstructor():void
		{
			// Create observer passing in notification method and context.
			var observer:puremvc.IObserver = new puremvc.Observer( this.observerTestMethod, this );

			/*
			 * Create a test notification, setting a body value and notify the observer with it. since the
			 * observer is this class and the notification method is observerTestMethod, successful
			 * notification will result in our local observerTestVar being set to the value we pass
			 * in on the notification body.
			 */
			var notification:puremvc.INotification = new puremvc.Notification( 'ObserverTestNote', 5 );
			observer.notifyObserver(notification);

			// test assertions
			YUITest.Assert.areSame
			(
				5,
				this.observerTestVar,
				"Expecting observerTestVar === 5"
			);
		}

		/**
		 * Tests the compareNotifyContext method of the Observer class.
		 */
		testCompareNotifyContext():void
		{
			// Create observer passing in notification method and context
			var observer:puremvc.IObserver = new puremvc.Observer( this.observerTestMethod, this );
			var negTestObj:Object = new Object();

			// test assertions
			YUITest.Assert.isFalse
			(
				observer.compareNotifyContext(negTestObj),
				"Expecting observer.compareNotifyContext(negTestObj) === false"
			);

			YUITest.Assert.isTrue
			(
				observer.compareNotifyContext(this),
				"Expecting observer.compareNotifyContext(this) === true"
			);
		}

		/**
		 * A function that is used as the observer notification method.
		 *
		 * @param notification
		 *		The <code>Notification</code> used to test that <code>Observer</code> is well
		 *		notified.
		 */
		private observerTestMethod( notification:puremvc.INotification ):void
		{
			this.observerTestVar = notification.getBody();
		}
	}
}